﻿namespace FitnessTrackerUI.ViewModel
{
    using System;
    using System.ComponentModel;
    using System.Linq;

    using FitnessTracker.DataStructures;
    using FitnessTracker.Observables;
    using FitnessTracker.Packet;

    public class WorkoutPagePropertiesViewModel : IObserver<HxMPacket>, INotifyPropertyChanged
    {
        private readonly FixedSizeQueue<int> nLatestHeartBeatsReceived = new FixedSizeQueue<int>(60);
        private byte currentHeartRate;
        private double movingHeartRateAverage;
        
        public event PropertyChangedEventHandler PropertyChanged;

        public WorkoutPagePropertiesViewModel()
        {
            // Preventing from running in the designer
            if (System.Windows.Application.Current.MainWindow == null)
            {
                return;
            }
            
            SerialPortReader.GetInstance("COM5").Subscribe(HxMReader.GetInstance());
            HxMReader.GetInstance().Subscribe(this);
        }

        public byte CurrentHeartRate
        {
            get
            {
                return this.currentHeartRate;
            }

            set
            {
                this.currentHeartRate = value;
                this.OnPropertyChanged("CurrentHeartRate");
            }
        }

        public double MovingHeartRateAverage
        {
            get
            {
                return this.movingHeartRateAverage;
            }

            set
            {
                this.movingHeartRateAverage = value;
                this.OnPropertyChanged("MovingHeartRateAverage");
            }
        }

        public void OnNext(HxMPacket packet)
        {
            this.CurrentHeartRate = packet.Payload.HeartRate;
            this.nLatestHeartBeatsReceived.Enqueue(this.CurrentHeartRate);
            this.MovingHeartRateAverage = Math.Round(this.nLatestHeartBeatsReceived.AsEnumerable().Average(), 1);
        }

        public void OnError(Exception error)
        {
            throw new NotImplementedException();
        }

        public void OnCompleted()
        {
            this.CurrentHeartRate = 0;
            this.MovingHeartRateAverage = 0;
        }

        private void OnPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
